package com.ruoyi.project.modules.interfaceinfo.controller;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.domain.entity.SysDictType;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.project.modules.errorCode.domain.ErrorCode;
import com.ruoyi.project.modules.frontInterfaceFieldSource.domain.FrontInterfaceFieldSource;
import com.ruoyi.project.modules.frontInterfaceFieldSource.service.IFrontInterfaceFieldSourceService;
import com.ruoyi.project.modules.interfaceinfo.domain.*;
import com.ruoyi.project.modules.interfaceinfo.service.IInterfaceInfoService;
import com.ruoyi.project.modules.interfaceinfo.service.IVirtualUsageService;
import com.ruoyi.project.modules.interfaceinfo.vo.InterfaceParam;
import com.ruoyi.project.modules.parameter.domain.InterfaceParamsFieldRelation;
import com.ruoyi.project.modules.parameter.domain.Params;
import com.ruoyi.project.modules.parameter.domain.ParamsFieldRelation;
import com.ruoyi.project.modules.parameter.mapper.InterfaceParamsFieldRelationMapper;
import com.ruoyi.project.modules.parameter.service.IInterfaceParamsFieldRelationService;
import com.ruoyi.project.modules.parameter.service.IParamsFieldRelationService;
import com.ruoyi.project.modules.parameter.service.IParamsService;
import com.ruoyi.project.modules.processBranch.domain.ProcessBranch;
import com.ruoyi.project.modules.processBranch.service.IProcessBranchService;
import com.ruoyi.project.modules.table.domain.FieldInfo;
import com.ruoyi.project.modules.table.service.ITableInfoService;
import com.ruoyi.project.modules.virtualUsageGroup.domain.VirtualUsageGroup;
import com.ruoyi.project.modules.virtualUsageGroup.service.IVirtualUsageGroupService;
import com.ruoyi.project.modules.virtualUsageGroupDetail.domain.VirtualUsageGroupDetail;
import com.ruoyi.project.modules.virtualUsageGroupDetail.service.IVirtualUsageGroupDetailService;
import com.ruoyi.project.modules.virtualUsageParamSource.domain.VirtualUsageParamSource;
import com.ruoyi.project.modules.virtualUsageParamSource.service.IVirtualUsageParamSourceService;
import com.ruoyi.system.service.ISysDictDataService;
import com.ruoyi.system.service.ISysDictTypeService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * TODO
 *
 * @author chenxiaoyu
 * @version 1.0
 * @date 2022/4/26 下午5:35
 */
@RestController
@RequestMapping("/dataRefresh")
@AllArgsConstructor
@Slf4j
public class DataRefreshController {
    private IInterfaceParamsFieldRelationService interfaceParamsFieldRelationService;

    private IParamsFieldRelationService paramsFieldRelationService;

    private ITableInfoService tableInfoService;

    private ISysDictTypeService sysDictTypeService;

    private ISysDictDataService sysDictDataService;

    private IInterfaceInfoService interfaceInfoService;

    private IVirtualUsageService virtualUsageService;

    private InterfaceParamsFieldRelationMapper interfaceParamsFieldRelationMapper;

    private IVirtualUsageGroupService virtualUsageGroupService;

    private IVirtualUsageParamSourceService virtualUsageParamSourceService;

    private IProcessBranchService processBranchService;

    private IVirtualUsageGroupDetailService virtualUsageGroupDetailService;

    private IFrontInterfaceFieldSourceService frontInterfaceFieldSourceService;

    private IParamsService paramsService;

    /**
     * 校验接口入参字段 模式设置 出现异常就重置
     * @return
     */
    @GetMapping("/fieldModel")
    public AjaxResult fieldModel() {
        List<SysDictData> pkType = this.sysDictTypeService.selectDictDataByType("pkType");
        List<SysDictData> fkType = this.sysDictTypeService.selectDictDataByType("fkType");
        List<SysDictData> timeType = this.sysDictTypeService.selectDictDataByType("timeType");
        List<SysDictData> otherType = this.sysDictTypeService.selectDictDataByType("otherType");
        Map<String, List<SysDictData>> pkMap = pkType.stream().collect(Collectors.groupingBy(SysDictData::getDictValue));
        Map<String, List<SysDictData>> fkMap = fkType.stream().collect(Collectors.groupingBy(SysDictData::getDictValue));
        Map<String, List<SysDictData>> timeMap = timeType.stream().collect(Collectors.groupingBy(SysDictData::getDictValue));
        Map<String, List<SysDictData>> otherMap = otherType.stream().collect(Collectors.groupingBy(SysDictData::getDictValue));
        InterfaceParamsFieldRelation interfaceParamsFieldRelation1 = new InterfaceParamsFieldRelation();
        interfaceParamsFieldRelation1.setIsInParam("1");
        interfaceParamsFieldRelation1.setObjectType("1");
        List<InterfaceParamsFieldRelation> interfaceParamsFieldRelationList = this.interfaceParamsFieldRelationService.selectInterfaceParamsFieldRelationList(interfaceParamsFieldRelation1);
        for (InterfaceParamsFieldRelation interfaceParamsFieldRelation : interfaceParamsFieldRelationList) {
            if (interfaceParamsFieldRelation.getIsInParam().equals("1") && interfaceParamsFieldRelation.getObjectType().equals("1")) {
                List<FieldInfo> fieldInfoList = this.tableInfoService.selectFieldInfoByFieldId(Arrays.asList(interfaceParamsFieldRelation.getObjectId()));
                if (exitsException(fieldInfoList.get(0), pkMap, fkMap, timeMap, otherMap, interfaceParamsFieldRelation.getIsUpdate(), interfaceParamsFieldRelation.getDesignContent())) {
                    interfaceParamsFieldRelation.setDesignContent("");
                    interfaceParamsFieldRelation.setIsUpdate("Y");
                    //this.interfaceParamsFieldRelationService.updateInterfaceParamsFieldRelation(interfaceParamsFieldRelation);
                    print(interfaceParamsFieldRelation.getId(), interfaceParamsFieldRelation, fieldInfoList.get(0));
                }
            }
        }

        List<ParamsFieldRelation> paramsFieldRelationList = this.paramsFieldRelationService.selectParamsFieldRelationList(new ParamsFieldRelation());
        for (ParamsFieldRelation paramsFieldRelation : paramsFieldRelationList) {
            InterfaceParamsFieldRelation interfaceParamsFieldRelation = this.interfaceParamsFieldRelationService.selectInterfaceParamsFieldRelationById(paramsFieldRelation.getInterfaceDataListId());
            if (interfaceParamsFieldRelation != null && interfaceParamsFieldRelation.getIsInParam().equals("1")) {
                List<FieldInfo> fieldInfoList = this.tableInfoService.selectFieldInfoByFieldId(Arrays.asList(paramsFieldRelation.getFieldId()));
                if (exitsException(fieldInfoList.get(0), pkMap, fkMap, timeMap, otherMap, paramsFieldRelation.getIsUpdate(), paramsFieldRelation.getDesignContent())) {
                    paramsFieldRelation.setDesignContent("");
                    paramsFieldRelation.setIsUpdate("Y");
                    //this.paramsFieldRelationService.updateParamsFieldRelation(paramsFieldRelation);
                    print(paramsFieldRelation.getId(), interfaceParamsFieldRelation, fieldInfoList.get(0));
                }
            }
        }
        log.info("end");
        return AjaxResult.success();
    }

    private void print(Long id, InterfaceParamsFieldRelation interfaceParamsFieldRelation,FieldInfo fieldInfo) {
        String interfaceName = null, slaveInterfaceName = null;
        if (interfaceParamsFieldRelation.getType().equals("3")) {
            VirtualUsage virtualUsage = new VirtualUsage();
            virtualUsage.setId(interfaceParamsFieldRelation.getInterfaceId());
            List<VirtualUsage> virtualUsages = this.virtualUsageService.selectVirtualUsages(virtualUsage);
            interfaceName = virtualUsages.get(0).getMasterInterfaceName();
            slaveInterfaceName = virtualUsages.get(0).getSlaveInterfaceName();
        } else {
            InterfaceInfo interfaceInfo = this.interfaceInfoService.selectInterfaceInfoById(interfaceParamsFieldRelation.getInterfaceId());
            interfaceName = interfaceInfo.getInterfaceName();
        }
        log.info("id:{}, interfaceName:{}, slaveInterfaceName:{}, fieldName: {}", id, interfaceName, slaveInterfaceName, fieldInfo.getFieldName());
    }

    private boolean exitsException(FieldInfo fieldInfo,
                                   Map<String, List<SysDictData>> pkMap,
                                   Map<String, List<SysDictData>> fkMap,
                                   Map<String, List<SysDictData>> timeMap,
                                   Map<String, List<SysDictData>> otherMap,
                                   String isUpdate,
                                   String designContent) {
        if (StringUtils.isNotEmpty(designContent)) {
            if (fieldInfo.getFieldType().equals("1")) {
                return !pkMap.containsKey(designContent);
            } else if (fieldInfo.getFieldType().equals("2")) {
                return !fkMap.containsKey(designContent);
            } else {
                if (fieldInfo.getIsFieldEnum().equals("Y")) {
                    List<SysDictData> sysDictDatas = new ArrayList<>();
                    if (fieldInfo.getDictId() != null) {
                        SysDictType sysDictType = this.sysDictTypeService.selectDictTypeById(fieldInfo.getDictId());
                        if (sysDictType != null) {
                            SysDictData dictData = new SysDictData();
                            dictData.setDictType(sysDictType.getDictType());
                            sysDictDatas = this.sysDictDataService.selectDictDataList(dictData);
                            for (SysDictData sysDictData : sysDictDatas) {
                                if (sysDictData.getDictValue().equals(designContent)) {
                                    return false;
                                }
                            }
                        }
                        return true;
                    } else {
                        return true;
                    }
                    //return false;
                } else if (fieldInfo.getFieldDataType().equals("3")) {
                    return !timeMap.containsKey(designContent);
                } else {
                    return !otherMap.containsKey(designContent);
                }
            }
        }
        return false;
    }

    @GetMapping("/fieldDataRelation")
    public AjaxResult fieldDataRelation() {
        InterfaceInfo interfaceInfo = new InterfaceInfo();
        interfaceInfo.setFbType("2");
        List<InterfaceInfo> interfaceInfoList = this.interfaceInfoService.selectInterfaceInfoList(interfaceInfo);
        for (InterfaceInfo info : interfaceInfoList) {
            VirtualUsage virtualUsage = new VirtualUsage();
            virtualUsage.setRelationInterfaceId(info.getId());
            List<VirtualUsage> virtualUsages = this.virtualUsageService.selectVirtualUsages(virtualUsage);
            if (CollectionUtil.isNotEmpty(virtualUsages)) {
                for (VirtualUsage usage : virtualUsages) {
                    handlerVirtualUsage(usage);
                }
            }
        }
        return AjaxResult.success();
    }

    private void handlerVirtualUsage(VirtualUsage usage) {
        List<InterfaceParam> interfaceParams = this.interfaceInfoService.paramList("3", usage.getId(), "1");
        checkParam(interfaceParams, usage, "1");
        interfaceParams = this.interfaceInfoService.paramList("3", usage.getId(), "2");
        checkParam(interfaceParams, usage, "1");
    }

    private void checkParam(List<InterfaceParam> interfaceParams, VirtualUsage usage, String type) {
        if (CollectionUtil.isNotEmpty(interfaceParams)) {
            for (InterfaceParam interfaceParam : interfaceParams) {
                String dataRelationType = interfaceParam.getDataRelationType();
                Long dataRelationId = interfaceParam.getDataRelationId();
                if (dataRelationId != null && dataRelationType != null) {
                    if ("1".equals(dataRelationType)) {
                        InterfaceParamsFieldRelation interfaceParamsFieldRelation = this.interfaceParamsFieldRelationService.selectInterfaceParamsFieldRelationById(dataRelationId);
                        if (interfaceParamsFieldRelation == null || !interfaceParamsFieldRelation.getInterfaceId().equals(usage.getInterfaceId())) {
                            log.info("id:{}, type: {}, interfaceName:{}, slaveInterfaceName:{}, fieldName: {}", interfaceParam.getId(),type, usage.getMasterInterfaceName(), usage.getSlaveInterfaceName(), interfaceParam.getFieldName());
                        }
                    } else {
                        ParamsFieldRelation paramsFieldRelation = this.paramsFieldRelationService.selectParamsFieldRelationById(dataRelationId);
                        if (paramsFieldRelation == null) {
                            log.info("id:{}, type: {}, interfaceName:{}, slaveInterfaceName:{}, fieldName: {}", interfaceParam.getId(),type, usage.getMasterInterfaceName(), usage.getSlaveInterfaceName(), interfaceParam.getFieldName());
                        } else {
                            InterfaceParamsFieldRelation interfaceParamsFieldRelation = this.interfaceParamsFieldRelationService.selectInterfaceParamsFieldRelationById(paramsFieldRelation.getInterfaceDataListId());
                            if (interfaceParamsFieldRelation == null || !interfaceParamsFieldRelation.getInterfaceId().equals(usage.getInterfaceId())) {
                                log.info("id:{}, type: {}, interfaceName:{}, slaveInterfaceName:{}, fieldName: {}", interfaceParam.getId(),type, usage.getMasterInterfaceName(), usage.getSlaveInterfaceName(), interfaceParam.getFieldName());
                            }
                        }
                    }
                }
                this.checkParam(interfaceParam.getChildren(), usage, "2");
            }
        }
    }

    @GetMapping("/printFieldModel")
    public void printFieldModel(HttpServletResponse response) throws IOException {
        List<SysDictData> pkType = this.sysDictTypeService.selectDictDataByType("pkType");
        List<SysDictData> fkType = this.sysDictTypeService.selectDictDataByType("fkType");
        List<SysDictData> timeType = this.sysDictTypeService.selectDictDataByType("timeType");
        List<SysDictData> otherType = this.sysDictTypeService.selectDictDataByType("otherType");
        Map<String, List<SysDictData>> pkMap = pkType.stream().collect(Collectors.groupingBy(SysDictData::getDictValue));
        Map<String, List<SysDictData>> fkMap = fkType.stream().collect(Collectors.groupingBy(SysDictData::getDictValue));
        Map<String, List<SysDictData>> timeMap = timeType.stream().collect(Collectors.groupingBy(SysDictData::getDictValue));
        Map<String, List<SysDictData>> otherMap = otherType.stream().collect(Collectors.groupingBy(SysDictData::getDictValue));
        List<InterfaceParam> interfaceParams = this.interfaceParamsFieldRelationMapper.fieldModelList();
        List<FieldModelDto> list = new ArrayList<>();
        for (InterfaceParam interfaceParam : interfaceParams) {
            List<FieldInfo> fieldInfoList = this.tableInfoService.selectFieldInfoByFieldId(Arrays.asList(interfaceParam.getFieldId()));
            FieldInfo fieldInfo = fieldInfoList.get(0);
            SysDictData sysDictData = null;
            if (StringUtils.isNotEmpty(interfaceParam.getDesignContent())) {
                if (fieldInfo.getFieldType().equals("1")) {
                    List<SysDictData> sysDictDataList = pkMap.get(interfaceParam.getDesignContent());
                    if (CollectionUtil.isNotEmpty(sysDictDataList)) {
                        sysDictData = sysDictDataList.get(0);
                    }
                } else if (fieldInfo.getFieldType().equals("2")) {
                    List<SysDictData> sysDictDataList = fkMap.get(interfaceParam.getDesignContent());
                    if (CollectionUtil.isNotEmpty(sysDictDataList)) {
                        sysDictData = sysDictDataList.get(0);
                    }
                } else if (fieldInfo.getIsFieldEnum().equals("Y")) {
                    List<SysDictData> sysDictDatas = new ArrayList<>();
                    if (fieldInfo.getDictId() != null) {
                        SysDictType sysDictType = this.sysDictTypeService.selectDictTypeById(fieldInfo.getDictId());
                        if (sysDictType != null) {
                            SysDictData dictData = new SysDictData();
                            dictData.setDictType(sysDictType.getDictType());
                            sysDictDatas = this.sysDictDataService.selectDictDataList(dictData);
                            if (CollectionUtil.isNotEmpty(sysDictDatas)) {
                                for (SysDictData data : sysDictDatas) {
                                    if (interfaceParam.getDesignContent().equals(data.getDictValue())) {
                                        sysDictData = data;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                } else if (fieldInfo.getFieldDataType().equals("3")) {
                    List<SysDictData> sysDictDataList = timeMap.get(interfaceParam.getDesignContent());
                    if (CollectionUtil.isNotEmpty(sysDictDataList)) {
                        sysDictData = sysDictDataList.get(0);
                    }
                } else {
                    List<SysDictData> sysDictDataList = otherMap.get(interfaceParam.getDesignContent());
                    if (CollectionUtil.isNotEmpty(sysDictDataList)) {
                        sysDictData = sysDictDataList.get(0);
                    }
                }
            }
            FieldModelDto fieldModelDto = new FieldModelDto();
            fieldModelDto.setFieldName(fieldInfo.getFieldName());
            fieldModelDto.setFieldEnName(fieldInfo.getFieldEnName());
            fieldModelDto.setFieldModelEnName(interfaceParam.getDesignContent());
            fieldModelDto.setFieldDescription(interfaceParam.getFieldDescription());
            fieldModelDto.setAliasName(interfaceParam.getAliasName());
            fieldModelDto.setAliasZhName(interfaceParam.getAliasZhName());
            fieldModelDto.setParamType("入参");
            if (sysDictData != null) {
                fieldModelDto.setFieldModelName(sysDictData.getDictLabel());
            }

            if (interfaceParam.getType().equals("3")) {
                VirtualUsage virtualUsage = new VirtualUsage();
                virtualUsage.setId(interfaceParam.getInterfaceId());
                List<VirtualUsage> virtualUsages = this.virtualUsageService.selectVirtualUsages(virtualUsage);
                fieldModelDto.setInterfaceName(virtualUsages.get(0).getMasterInterfaceName());
                fieldModelDto.setVirtualUsageName(virtualUsages.get(0).getSlaveInterfaceName());
            } else if (interfaceParam.getType().equals("5")) {
                VirtualUsageGroup virtualUsageGroup = this.virtualUsageGroupService.selectVirtualUsageGroupById(interfaceParam.getInterfaceId());
                fieldModelDto.setInterfaceName(virtualUsageGroup.getGroupName());
            } else {
                InterfaceInfo interfaceInfo = this.interfaceInfoService.selectInterfaceInfoById(interfaceParam.getInterfaceId());
                fieldModelDto.setInterfaceName(interfaceInfo.getInterfaceName());
            }
            list.add(fieldModelDto);
        }
        interfaceParams = this.interfaceParamsFieldRelationMapper.fieldModelListByOutParam();
        for (InterfaceParam interfaceParam : interfaceParams) {
            List<FieldInfo> fieldInfoList = this.tableInfoService.selectFieldInfoByFieldId(Arrays.asList(interfaceParam.getFieldId()));
            FieldInfo fieldInfo = fieldInfoList.get(0);
            FieldModelDto fieldModelDto = new FieldModelDto();
            fieldModelDto.setIsAllowEmpty(interfaceParam.getIsAllowEmpty());
            fieldModelDto.setOtherModel(interfaceParam.getOtherModel());
            fieldModelDto.setFieldName(fieldInfo.getFieldName());
            fieldModelDto.setFieldEnName(fieldInfo.getFieldEnName());
            fieldModelDto.setFieldModelEnName(interfaceParam.getDesignContent());
            fieldModelDto.setFieldDescription(interfaceParam.getFieldDescription());
            fieldModelDto.setAliasName(interfaceParam.getAliasName());
            fieldModelDto.setAliasZhName(interfaceParam.getAliasZhName());
            fieldModelDto.setParamType("出参");
            if (interfaceParam.getType().equals("3")) {
                VirtualUsage virtualUsage = new VirtualUsage();
                virtualUsage.setId(interfaceParam.getInterfaceId());
                List<VirtualUsage> virtualUsages = this.virtualUsageService.selectVirtualUsages(virtualUsage);
                fieldModelDto.setInterfaceName(virtualUsages.get(0).getMasterInterfaceName());
                fieldModelDto.setVirtualUsageName(virtualUsages.get(0).getSlaveInterfaceName());
            } else if (interfaceParam.getType().equals("5")) {
                VirtualUsageGroup virtualUsageGroup = this.virtualUsageGroupService.selectVirtualUsageGroupById(interfaceParam.getInterfaceId());
                fieldModelDto.setInterfaceName(virtualUsageGroup.getGroupName());
            } else {
                InterfaceInfo interfaceInfo = this.interfaceInfoService.selectInterfaceInfoById(interfaceParam.getInterfaceId());
                fieldModelDto.setInterfaceName(interfaceInfo.getInterfaceName());
            }
            list.add(fieldModelDto);
        }
        ExcelUtil<FieldModelDto> util = new ExcelUtil<>(FieldModelDto.class);
        AjaxResult result = util.exportExcel(list, "字段模式");
        String fileName = (String) result.get("msg");
        String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1);
        String filePath = RuoYiConfig.getDownloadPath() + fileName;

        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
        FileUtils.setAttachmentResponseHeader(response, realFileName);
        FileUtils.writeBytes(filePath, response.getOutputStream());

        FileUtils.deleteFile(filePath);
    }

    /**
     * 打印method入参必填,扫所有调用这个method的虚拟用况,没有传必填字段,就拉出来
     * 比如 method 三个参数, ABC   A是必填,BC 不是必填字段
     * 第一个虚拟用况调用这个method的时候只传了A ,BC 裁剪掉了,这就没问题
     * 第二个虚拟用况调用这个method的时候,传了BC,没传A ,那就有问题,要找出来
     * @param response
     * @throws IOException
     */
    @GetMapping("/printInValidFieldRequired")
    public void printInValidFieldRequired(HttpServletResponse response) throws IOException {
        List<InterfaceInfo> interfaceInfoList = this.interfaceInfoService.selectInterfaceInfoList(new InterfaceInfo());
        Map<Long, List<InterfaceParam>> cache = new HashMap<>();
        Map<Long, VirtualUsage> cache2 = new HashMap<>();
        List<FieldRequiredDto> list = new ArrayList<>();
        for (InterfaceInfo interfaceInfo : interfaceInfoList) {
            if (interfaceInfo.getFbType().equals("2") || interfaceInfo.getFbType().equals("3")) {
                check(interfaceInfo, list, cache, cache2);
            }
        }

        ExcelUtil<FieldRequiredDto> util = new ExcelUtil<>(FieldRequiredDto.class);
        AjaxResult result = util.exportExcel(list, "字段必填");
        String fileName = (String) result.get("msg");
        String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1);
        String filePath = RuoYiConfig.getDownloadPath() + fileName;

        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
        FileUtils.setAttachmentResponseHeader(response, realFileName);
        FileUtils.writeBytes(filePath, response.getOutputStream());

        FileUtils.deleteFile(filePath);
    }

    private void check(InterfaceInfo interfaceInfo, List<FieldRequiredDto> result, Map<Long, List<InterfaceParam>> cache, Map<Long, VirtualUsage> cache2) {
        if ("Y".equals(interfaceInfo.getIsBranch())) {
            ProcessBranch processBranch = new ProcessBranch();
            processBranch.setInterfaceId(interfaceInfo.getId());
            List<ProcessBranch> processBranches = this.processBranchService.selectProcessBranchList(processBranch);
            for (ProcessBranch branch : processBranches) {
                if ("1".equals(branch.getType())) {
                    VirtualUsage virtualUsage = cache2.get(branch.getEntityId());
                    if (virtualUsage == null) {
                        VirtualUsage usage = new VirtualUsage();
                        usage.setId(branch.getEntityId());
                        List<VirtualUsage> virtualUsages = this.virtualUsageService.selectVirtualUsages(usage);
                        if (CollectionUtil.isNotEmpty(virtualUsages)) {
                            cache2.put(branch.getEntityId(), virtualUsages.get(0));
                            virtualUsage = virtualUsages.get(0);
                        } else {
                            log.error("异常， {}", JSONObject.toJSONString(branch));
                        }
                    }
                    if (virtualUsage == null) continue;
                    List<InterfaceParam> interfaceParams = cache.get(virtualUsage.getInterfaceId());
                    // 查询method或者dubbo
                    if (interfaceParams == null) {
                        if (interfaceInfo.getFbType().equals("3")) {
                            interfaceParams = this.interfaceInfoService.paramRequiredList("1", interfaceInfo.getId(), "1");
                        } else {
                            interfaceParams = this.interfaceInfoService.paramRequiredList("4", interfaceInfo.getId(), "1");
                        }
                        // 缓存
                        cache.put(virtualUsage.getInterfaceId(), interfaceParams);
                    }
                    List<InterfaceParam> interfaceParamList = this.interfaceInfoService.virtualUsageInParamList("3", branch.getEntityId(), branch.getProcessBranchId(), null);
                    interfaceParamList = this.queryRequired(interfaceParamList);
                    Map<Long, List<InterfaceParam>> collect = interfaceParamList.stream().collect(Collectors.groupingBy(InterfaceParam::getFieldId));
                    for (InterfaceParam interfaceParam : interfaceParams) {
                        if (!collect.containsKey(interfaceParam.getFieldId())) {
                            FieldRequiredDto dto = new FieldRequiredDto();
                            dto.setFieldName(interfaceParam.getFieldName());
                            dto.setInterfaceName1(virtualUsage.getMasterInterfaceName());
                            dto.setVirtualUsageName(virtualUsage.getSlaveInterfaceName());
                            result.add(dto);
                        }
                    }
                } else if ("4".equals(branch.getType())) {
                    VirtualUsageGroup virtualUsageGroup = this.virtualUsageGroupService.selectVirtualUsageGroupById(branch.getEntityId());
                    VirtualUsageGroupDetail virtualUsageGroupDetail = new VirtualUsageGroupDetail();
                    virtualUsageGroupDetail.setGroupId(branch.getEntityId());
                    List<VirtualUsageGroupDetail> virtualUsageGroupDetails = this.virtualUsageGroupDetailService.selectVirtualUsageGroupDetailList(virtualUsageGroupDetail);
                    for (VirtualUsageGroupDetail usageGroupDetail : virtualUsageGroupDetails) {
                        Long virtualUsageId = usageGroupDetail.getVirtualUsageId();
                        VirtualUsage virtualUsage = cache2.get(virtualUsageId);
                        if (virtualUsage == null) {
                            VirtualUsage usage = new VirtualUsage();
                            usage.setId(virtualUsageId);
                            List<VirtualUsage> virtualUsages = this.virtualUsageService.selectVirtualUsages(usage);
                            if (CollectionUtil.isNotEmpty(virtualUsages)) {
                                cache2.put(virtualUsageId, virtualUsages.get(0));
                                virtualUsage = virtualUsages.get(0);
                            } else {
                                log.error("异常， {}", JSONObject.toJSONString(branch));
                            }
                        }
                        if (virtualUsage == null) continue;
                        Long interfaceId = virtualUsage.getInterfaceId();
                        List<InterfaceParam> interfaceParams = cache.get(interfaceId);
                        // 查询method或者dubbo
                        if (interfaceParams == null) {
                            if (interfaceInfo.getFbType().equals("3")) {
                                interfaceParams = this.interfaceInfoService.paramRequiredList("1", interfaceId, "1");
                            } else {
                                interfaceParams = this.interfaceInfoService.paramRequiredList("4", interfaceId, "1");
                            }
                            // 缓存
                            cache.put(interfaceId, interfaceParams);
                        }
                        List<InterfaceParam> interfaceParamList = this.interfaceInfoService.virtualUsageInParamList("3", virtualUsageId, null, branch.getEntityId());
                        interfaceParamList = this.queryRequired(interfaceParamList);
                        Map<Long, List<InterfaceParam>> collect = interfaceParamList.stream().collect(Collectors.groupingBy(InterfaceParam::getFieldId));
                        for (InterfaceParam interfaceParam : interfaceParams) {
                            if (!collect.containsKey(interfaceParam.getFieldId())) {
                                FieldRequiredDto dto = new FieldRequiredDto();
                                dto.setFieldName(interfaceParam.getFieldName());
                                dto.setInterfaceName1(virtualUsage.getMasterInterfaceName());
                                dto.setVirtualUsageName(virtualUsage.getSlaveInterfaceName());
                                dto.setGroupName(virtualUsageGroup.getGroupName());
                                result.add(dto);
                            }
                        }
                    }
                }
            }
        } else {
            // 查询虚拟用况
            VirtualUsage virtualUsage = new VirtualUsage();
            virtualUsage.setRelationInterfaceId(interfaceInfo.getId());
            List<VirtualUsage> virtualUsages = this.virtualUsageService.selectVirtualUsages(virtualUsage);
            if (CollectionUtil.isNotEmpty(virtualUsages)) {
                for (VirtualUsage usage : virtualUsages) {
                    Long interfaceId = usage.getInterfaceId();
                    List<InterfaceParam> interfaceParams = cache.get(interfaceId);
                    // 查询method或者dubbo
                    if (interfaceParams == null) {
                        if (interfaceInfo.getFbType().equals("3")) {
                            interfaceParams = this.interfaceInfoService.paramRequiredList("1", interfaceId, "1");
                        } else {
                            interfaceParams = this.interfaceInfoService.paramRequiredList("4", interfaceId, "1");
                        }
                        // 缓存
                        cache.put(interfaceId, interfaceParams);
                    }
                    List<InterfaceParam> interfaceParamList = this.interfaceInfoService.virtualUsageInParamList("3", usage.getId(), null, null);
                    interfaceParamList = this.queryRequired(interfaceParamList);
                    Map<Long, List<InterfaceParam>> collect = interfaceParamList.stream().collect(Collectors.groupingBy(InterfaceParam::getFieldId));
                    for (InterfaceParam interfaceParam : interfaceParams) {
                        if (!collect.containsKey(interfaceParam.getFieldId())) {
                            FieldRequiredDto dto = new FieldRequiredDto();
                            dto.setFieldName(interfaceParam.getFieldName());
                            dto.setInterfaceName1(usage.getMasterInterfaceName());
                            dto.setVirtualUsageName(usage.getSlaveInterfaceName());
                            result.add(dto);
                        }
                    }
                }
            }
        }
    }

    private List<InterfaceParam> queryRequired(List<InterfaceParam> interfaceParams) {
        List<InterfaceParam> result = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(interfaceParams)) {
            for (InterfaceParam interfaceParam : interfaceParams) {
                if ("1".equals(interfaceParam.getObjectType())) {
                    if (StringUtils.isNotEmpty(interfaceParam.getDesignContent()) || interfaceParam.getDataRelationId() != null) {
                        result.add(interfaceParam);
                    }
                }
                if (CollectionUtil.isNotEmpty(interfaceParam.getChildren())) {
                    for (InterfaceParam child : interfaceParam.getChildren()) {
                        if (StringUtils.isNotEmpty(child.getDesignContent()) || child.getDataRelationId() != null) {
                            result.add(child);
                        }
                    }
                }
            }
        }
        return result;
    }

    /** 
     * 一个是虚拟用况 入参字段 来源和模式
     * 二者必选一,不能两个都没有  打印出来
     * @author chenxiaoyu
     * @date 2022/5/11 下午11:39
     * @param response 
     * @return void
     */ 
    @GetMapping("/printInValidVirtualUsageField")
    public void printInValidVirtualUsageField(HttpServletResponse response) throws IOException {
        List<VuFieldModelDto> list = new ArrayList<>();
        List<InterfaceInfo> interfaceInfoList = this.interfaceInfoService.selectInterfaceInfoList(new InterfaceInfo());
        for (InterfaceInfo interfaceInfo : interfaceInfoList) {
            if (interfaceInfo.getFbType().equals("2") || interfaceInfo.getFbType().equals("3")) {
                if ("N".equals(interfaceInfo.getIsBranch())) {
                    VirtualUsage virtualUsage1 = new VirtualUsage();
                    virtualUsage1.setRelationInterfaceId(interfaceInfo.getId());
                    List<VirtualUsage> virtualUsages = this.virtualUsageService.selectVirtualUsages(virtualUsage1);
                    for (VirtualUsage virtualUsage : virtualUsages) {
                        List<InterfaceParam> interfaceParams = this.interfaceInfoService.paramList("3", virtualUsage.getId(), "1");
                        for (InterfaceParam interfaceParam : interfaceParams) {
                            VuFieldModelDto dto = checkVUField(interfaceParam, null, null);
                            if (dto != null) {
                                dto.setInterfaceName(virtualUsage.getMasterInterfaceName());
                                dto.setVirtualUsageName(virtualUsage.getSlaveInterfaceName());
                                list.add(dto);
                            }
                        }
                    }
                } else {
                    ProcessBranch processBranch = new ProcessBranch();
                    processBranch.setInterfaceId(interfaceInfo.getId());
                    List<ProcessBranch> processBranches = this.processBranchService.selectProcessBranchList(processBranch);
                    for (ProcessBranch branch : processBranches) {
                        if (branch.getType().equals("1")) {
                            List<InterfaceParam> interfaceParams = this.interfaceInfoService.paramList("3", branch.getEntityId(), "1");
                            for (InterfaceParam interfaceParam : interfaceParams) {
                                VuFieldModelDto dto = checkVUField(interfaceParam, branch.getProcessBranchId(), null);
                                if (dto != null) {
                                    VirtualUsage virtualUsage = new VirtualUsage();
                                    virtualUsage.setId(branch.getEntityId());
                                    List<VirtualUsage> virtualUsages = this.virtualUsageService.selectVirtualUsages(virtualUsage);
                                    dto.setInterfaceName(virtualUsages.get(0).getMasterInterfaceName());
                                    dto.setVirtualUsageName(virtualUsages.get(0).getSlaveInterfaceName());
                                    list.add(dto);
                                }
                            }
                        } else if (branch.getType().equals("4")) {
                            VirtualUsageGroupDetail virtualUsageGroupDetail = new VirtualUsageGroupDetail();
                            virtualUsageGroupDetail.setGroupId(branch.getEntityId());
                            List<VirtualUsageGroupDetail> virtualUsageGroupDetails = this.virtualUsageGroupDetailService.selectVirtualUsageGroupDetailList(virtualUsageGroupDetail);
                            for (VirtualUsageGroupDetail usageGroupDetail : virtualUsageGroupDetails) {
                                List<InterfaceParam> interfaceParams = this.interfaceInfoService.paramList("3", usageGroupDetail.getVirtualUsageId(), "1");
                                for (InterfaceParam interfaceParam : interfaceParams) {
                                    VuFieldModelDto dto = checkVUField(interfaceParam, null, branch.getEntityId());
                                    if (dto != null) {
                                        VirtualUsage virtualUsage = new VirtualUsage();
                                        virtualUsage.setId(usageGroupDetail.getVirtualUsageId());
                                        List<VirtualUsage> virtualUsages = this.virtualUsageService.selectVirtualUsages(virtualUsage);
                                        dto.setInterfaceName(virtualUsages.get(0).getMasterInterfaceName());
                                        dto.setVirtualUsageName(virtualUsages.get(0).getSlaveInterfaceName());
                                        VirtualUsageGroup virtualUsageGroup = this.virtualUsageGroupService.selectVirtualUsageGroupById(branch.getEntityId());
                                        dto.setGroupName(virtualUsageGroup.getGroupName());
                                        list.add(dto);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        ExcelUtil<VuFieldModelDto> util = new ExcelUtil<>(VuFieldModelDto.class);
        AjaxResult result = util.exportExcel(list, "字段模式来源必填");
        String fileName = (String) result.get("msg");
        String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1);
        String filePath = RuoYiConfig.getDownloadPath() + fileName;

        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
        FileUtils.setAttachmentResponseHeader(response, realFileName);
        FileUtils.writeBytes(filePath, response.getOutputStream());

        FileUtils.deleteFile(filePath);
    }

    private VuFieldModelDto checkVUField(InterfaceParam interfaceParam, Long processId, Long virtualUsageGroupId) {
        if ("1".equals(interfaceParam.getObjectType())) {
            // 查询来源
            VirtualUsageParamSource virtualUsageParamSource = new VirtualUsageParamSource();
            virtualUsageParamSource.setObjectIds(Arrays.asList(interfaceParam.getId()));
            virtualUsageParamSource.setType("1");
            virtualUsageParamSource.setIsInParam("1");
            virtualUsageParamSource.setProcessBranchId(processId);
            virtualUsageParamSource.setVirtualUsageGroupId(virtualUsageGroupId);
            List<VirtualUsageParamSource> virtualUsageParamSourceList = this.virtualUsageParamSourceService.selectVirtualUsageParamSourceList2(virtualUsageParamSource);
            if (StringUtils.isNotEmpty(interfaceParam.getDesignContent()) && CollectionUtil.isNotEmpty(virtualUsageParamSourceList)) {
                VuFieldModelDto dto = new VuFieldModelDto();
                dto.setFieldName(interfaceParam.getFieldName());
                return dto;
            } else if (!StringUtils.isNotEmpty(interfaceParam.getDesignContent()) && !CollectionUtil.isNotEmpty(virtualUsageParamSourceList)) {
                VuFieldModelDto dto = new VuFieldModelDto();
                dto.setFieldName(interfaceParam.getFieldName());
                return dto;
            }
        }
        if (CollectionUtil.isNotEmpty(interfaceParam.getChildren())) {
            for (InterfaceParam child : interfaceParam.getChildren()) {
                // 查询来源
                VirtualUsageParamSource virtualUsageParamSource = new VirtualUsageParamSource();
                virtualUsageParamSource.setObjectIds(Arrays.asList(child.getId()));
                virtualUsageParamSource.setType("2");
                virtualUsageParamSource.setIsInParam("1");
                virtualUsageParamSource.setProcessBranchId(processId);
                virtualUsageParamSource.setVirtualUsageGroupId(virtualUsageGroupId);
                List<VirtualUsageParamSource> virtualUsageParamSourceList = this.virtualUsageParamSourceService.selectVirtualUsageParamSourceList2(virtualUsageParamSource);
                if (StringUtils.isNotEmpty(child.getDesignContent()) && CollectionUtil.isNotEmpty(virtualUsageParamSourceList)) {
                    VuFieldModelDto dto = new VuFieldModelDto();
                    dto.setFieldName(child.getFieldName());
                    return dto;
                } else if (!StringUtils.isNotEmpty(child.getDesignContent()) && !CollectionUtil.isNotEmpty(virtualUsageParamSourceList)) {
                    VuFieldModelDto dto = new VuFieldModelDto();
                    dto.setFieldName(child.getFieldName());
                    return dto;
                }

            }
        }
        return null;
    }

    /**
     * 刷前端接口字段来源数据
     * @return
     */
    @GetMapping("/refreshFrontFieldSource")
    public AjaxResult refreshFrontFieldSource() {
        FrontInterfaceFieldSource frontInterfaceFieldSource = new FrontInterfaceFieldSource();
        List<FrontInterfaceFieldSource> frontInterfaceFieldSources = this.frontInterfaceFieldSourceService.selectFrontInterfaceFieldSourceList(frontInterfaceFieldSource);
        if (CollectionUtil.isNotEmpty(frontInterfaceFieldSources)) {
            for (FrontInterfaceFieldSource interfaceFieldSource : frontInterfaceFieldSources) {
                if (interfaceFieldSource.getSourceType().equals("1") || interfaceFieldSource.getSourceType().equals("3")) {
                    InterfaceInfo interfaceInfo = this.interfaceInfoService.selectInterfaceInfoById(interfaceFieldSource.getSourceInterfaceId());
                    interfaceFieldSource.setSourceInterfaceName(interfaceInfo.getInterfaceName());
                    interfaceFieldSource.setSourceInterfaceUrl(interfaceInfo.getInterfaceUrl());

                    Long sourceObjectId = interfaceFieldSource.getSourceObjectId();
                    InterfaceParamsFieldRelation interfaceParamsFieldRelation = this.interfaceParamsFieldRelationMapper.selectInterfaceParamsFieldRelationById(sourceObjectId);
                    if (interfaceParamsFieldRelation != null) {
                        if (interfaceParamsFieldRelation.getObjectType().equals("1")) {
                            List<FieldInfo> fieldInfoList = this.tableInfoService.selectFieldInfoByFieldId(Arrays.asList(interfaceParamsFieldRelation.getObjectId()));
                            interfaceFieldSource.setSourceObjectEnName(fieldInfoList.get(0).getFieldEnName());
                            interfaceFieldSource.setSourceObjectName(fieldInfoList.get(0).getFieldName());
                        } else {
                            Params params = this.paramsService.selectParamsById(interfaceParamsFieldRelation.getObjectId());
                            interfaceFieldSource.setSourceObjectEnName(params.getEnName());
                            interfaceFieldSource.setSourceObjectName(params.getZhName());

                            ParamsFieldRelation paramsFieldRelation = this.paramsFieldRelationService.selectParamsFieldRelationById(interfaceFieldSource.getSourceObjectFieldId());
                            List<FieldInfo> fieldInfoList = this.tableInfoService.selectFieldInfoByFieldId(Arrays.asList(paramsFieldRelation.getFieldId()));
                            interfaceFieldSource.setSourceObjectFieldEnName(fieldInfoList.get(0).getFieldEnName());
                            interfaceFieldSource.setSourceObjectFieldName(fieldInfoList.get(0).getFieldName());
                        }
                        this.frontInterfaceFieldSourceService.updateFrontInterfaceFieldSource(interfaceFieldSource);
                    } else {
                        log.error("id:{}", interfaceFieldSource.getId());
                    }
                }
            }
        }
        return AjaxResult.success();
    }
}
